namespace AnalyStock.GrapImage;

/// <summary>
///     画分时图，查看分时图
/// </summary>
public partial class ChartKline : UserControl
{
    private float MaxPriceChange_Minute, MinPriceChange_Minute;

    private bool IsMinutePanelVisible => MintuePricePanel.IsVisible;

    private bool IsZoom { get; set; }

    private void InitializePanel_ChartMintue()
    {
        MintuePricePanel.Visibility = Visibility.Hidden;
        MintuePricePanel.InitializeMouseDarg(this);
        BtnZoomMintuePanel.Click += MintuePricePanelZoomed_Click;
    }

    private void MintuePricePanel_OpenToClose()
    {
        if (MintuePricePanel.IsVisible)
        {
            MintuePricePanel.Visibility = Visibility.Hidden;
            return;
        }

        MintuePricePanel.Visibility = Visibility.Visible;
    }

    private void MintuePricePanelZoomed_Click(object sender, RoutedEventArgs e)
    {
        IsZoom = !IsZoom;
        var zoomSizeVal = IsZoom ? 60.0 : -60.0;
        BtnZoomMintuePanel.Content = IsZoom ? "⇘" : "⇖";
        MintuePricePanel.Width += zoomSizeVal;
        MintuePricePanel.Height += zoomSizeVal;
        MintuePricePanel.UpdateLayout();
        PaintMintuePanel();
    }

    private void PaintMintuePanel()
    {
        MintueCanvas.Children.Clear();
        if (currKlinedata.MinuteDatas.IsNullOrEmpty())
        {
            return;
        }

        GetMaxMinPrice_Mintue();
        PaintMarkLineOnXaxis_Mintue();
        PaintMarkLineOnYaxis_Mintue();
        PaintTimelyPriceLine_Mintue();
        PaintVolume_Mintue();
    }

    /// <summary>
    ///     涨跌停价格
    /// </summary>
    private void GetMaxMinPrice_Mintue()
    {
        var code = currKlinedata.MinuteDatas.FirstOrDefault().Ts_code[..2];
        var yestClose = currKlinedata.MinuteDatas.FirstOrDefault().Yestclose;
        //是否创业板 
        var isSecondBoard = code is "30" or "68";
        MaxPriceChange_Minute = yestClose * (isSecondBoard ? 1.20f : 1.10f);
        MinPriceChange_Minute = yestClose * (isSecondBoard ? 0.80f : 0.90f);
    }

    /// <summary>
    ///     画X轴标志线
    /// </summary>
    private void PaintMarkLineOnXaxis_Mintue()
    {
        var unit_price = (MaxPriceChange_Minute - MinPriceChange_Minute) / 12;
        var unitSize_High_Minute = MintueCanvas.ActualHeight / 12;
        var yestclose = currKlinedata.MinuteDatas.First().Yestclose;
        double y_Line, price_Change;
        for (var i = 0; i < 13; i++)
        {
            y_Line = MintueCanvas.ActualHeight - (i * unitSize_High_Minute);
            new Line
            {
                X1 = 0,
                Y1 = y_Line,
                X2 = MintueCanvas.ActualWidth,
                Y2 = y_Line,
                Stroke = Brushes.DarkGray,
                StrokeThickness = i is 6 ? 0.4 : 0.2,
                StrokeDashArray = i is 6 ? new DoubleCollection { 20, 4 } : default //画虚线
            }.WithPanel(MintueCanvas);
            new TextBlock
            {
                Text = $"{MinPriceChange_Minute + (i * unit_price):F2}",
                FontSize = 7,
                Foreground = i < 6 ? Brushes.LimeGreen : Brushes.IndianRed
            }.SetPostion(y_Line - 3.50, -25.0).WithPanel(MintueCanvas);
            //画价格增幅刻度值
            price_Change = (((MinPriceChange_Minute + (i * unit_price)) / yestclose) - 1.00) * 100.0;
            new TextBlock
            {
                Text = $"{price_Change:F1}",
                FontSize = 7,
                Foreground = i < 6 ? Brushes.LimeGreen : Brushes.IndianRed
            }.SetPostion(y_Line - 3.50, MintueCanvas.ActualWidth).WithPanel(MintueCanvas);
        }
    }

    /// <summary>
    ///     画Y轴标志线
    /// </summary>
    private void PaintMarkLineOnYaxis_Mintue()
    {
        var unitSize_Width_Halfhour = MintueCanvas.ActualWidth / 8.0f;
        var timeTable = new[] { "9:30", "10:00", "10:30", "11:00", "11:30", "13:30", "14:00", "14:30", "15:00" };
        double X_Line;
        for (var i = 0; i < 9; i++)
        {
            X_Line = i * unitSize_Width_Halfhour;
            new Line
            {
                X1 = X_Line,
                Y1 = 0,
                X2 = X_Line,
                Y2 = MintueCanvas.ActualHeight,
                Stroke = Brushes.DarkGray,
                StrokeThickness = 0.2
            }.WithPanel(MintueCanvas);
            //画时间刻度值
            new TextBlock
            {
                Text = $"{timeTable[i]}",
                FontSize = 7,
                Foreground = Brushes.Gray
            }.SetPostion(-12.0, X_Line - 10.0).WithPanel(MintueCanvas);
        }
    }

    /// <summary>
    ///     画价格分时线
    /// </summary>
    private void PaintTimelyPriceLine_Mintue()
    {
        var i = 0;
        var unitIndexSize_Width_Mintue
            = MintueCanvas.ActualWidth / 242; // minuteDatas.Count;
        var unitPriceSize_High_Mintue
            = MintueCanvas.ActualHeight / (MaxPriceChange_Minute - MinPriceChange_Minute);
        var changePrice = MaxPriceChange_Minute - MinPriceChange_Minute;
        var points_Timely = new PointCollection(currKlinedata.MinuteDatas.Count);
        var points_Mean = new PointCollection(currKlinedata.MinuteDatas.Count);
        var x_Point = 0.0;
        foreach (var item in currKlinedata.MinuteDatas)
        {
            x_Point = i++ * unitIndexSize_Width_Mintue;
            var y_PointOnTimely
                = (MaxPriceChange_Minute - item.Price_timely) * unitPriceSize_High_Mintue;
            var y_PointOnMean
                = (MaxPriceChange_Minute - item.Price_mean) * unitPriceSize_High_Mintue;
            points_Timely.Add(new Point(x_Point, y_PointOnTimely));
            points_Mean.Add(new Point(x_Point, y_PointOnMean));
        }

        points_Timely.PolylineWithGop(MintueCanvas, new ShapeParam
        {
            FillColor = Colors.DeepSkyBlue,
            StrokeThickness = 0.8,
            Gop_Opacity = 0.3
        });
        points_Mean.PolylineWithGop(MintueCanvas, new ShapeParam
        {
            FillColor = Colors.DarkOrange,
            StrokeThickness = 0.6,
            Gop_Opacity = 0.3,
            IsOnlyPolyline = true,
            StrokeDashArray = new DoubleCollection { 10, 5 }
        });
    }

    private void PaintVolume_Mintue()
    {
        var maxVolume = currKlinedata.MinuteDatas.Max(n => n.Volume);
        if (maxVolume is 0)
        {
            return;
        }

        var volume_Height_Mintue = 60.0; //交易量线占60个单位像素点
        var unitSize_Volume_Minute = volume_Height_Mintue / maxVolume;
        var unitIndexSize_Width_Mintue
            = MintueCanvas.ActualWidth / 240; // minuteDatas.Count;
        var i = 0;
        var lastPrice = currKlinedata.MinuteDatas.First().Yestclose;
        foreach (var item in currKlinedata.MinuteDatas)
        {
            var XPoint = i++ * unitIndexSize_Width_Mintue;
            //交易量线
            new Line
            {
                X1 = XPoint,
                Y1 = MintueCanvas.ActualHeight - volume_Height_Mintue +
                     ((maxVolume - item.Volume) * unitSize_Volume_Minute),
                X2 = XPoint,
                Y2 = MintueCanvas.ActualHeight,
                StrokeThickness = 0.3,
                Stroke = item.Price_timely > lastPrice ? Brushes.Red
                    : item.Price_timely < lastPrice ? Brushes.LimeGreen
                    : Brushes.DarkGray
            }.WithPanel(MintueCanvas);
            //保存价格值
            lastPrice = item.Price_timely;
        }
    }
}